package modelo;

import geometria.Coordenada;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;

/**
 * 
 * Contiene la informacion asociada a la cantidad de naves, su velocidad y las
 * pistas existentes. Contiene el comportamiento que define de que manera van
 * apareciendo naves
 * 
 */
public class Nivel {

	// Las aeronaves que vamos a ir mandando, las generamos de entrada
	private ArrayList<AeroNave> navesRestantes;
	private ArrayList<Pista> pistas;
	private Double factorDeVelocidad = 0D;

	// Este contador lo usamos para ver si ya es hora de mandar una nave, cuando
	// se manda se resetea
	private long contadorApariciones;
	private long intervaloApariciones;

	private int avionesSimples, avionesPesados, avionesComputarizados,
			helicopteros;

	public Nivel() {
		this.navesRestantes = new ArrayList<AeroNave>();
		this.pistas = new ArrayList<Pista>();

	}

	public void setAvionesSimples(int avionesSimples) {
		this.avionesSimples = avionesSimples;
	}

	public void setAvionesPesados(int avionesPesados) {
		this.avionesPesados = avionesPesados;
	}

	public void setAvionesComputarizados(int avionesComputarizados) {
		this.avionesComputarizados = avionesComputarizados;
	}

	public void setHelicopteros(int helicopteros) {
		this.helicopteros = helicopteros;
	}

	/**
	 * Genera la lista interna de naves
	 * 
	 * @param cantidad
	 * @throws PistaNoDisponibleException
	 */
	public void generarNaves() throws PistaNoDisponibleException {
		Random generator = new Random();
		Escenario escenario = Escenario.getInstance();
		Double xmax = escenario.getXMax();
		Double ymax = escenario.getYMax();

		// tal vez aca sea razonable usar reflection, teniendo un array list de
		// Methods o algo por el estilo
		while (this.avionesSimples > 0) {
			// http://stackoverflow.com/questions/3680637/how-to-generate-a-random-double-in-a-given-range
			Double x = (xmax) * generator.nextDouble();
			Double y = (ymax) * generator.nextDouble();
			navesRestantes.add(AeroNaveFactory.getAvionSimple(new Coordenada(x,
					y)));
			this.avionesSimples -= 1;
		}
		while (this.helicopteros > 0) {
			Double x = (xmax) * generator.nextDouble();
			Double y = (ymax) * generator.nextDouble();
			navesRestantes.add(AeroNaveFactory.getHelicoptero(new Coordenada(x,
					y)));
			this.helicopteros -= 1;
		}

		while (this.avionesPesados > 0) {
			Double x = (xmax) * generator.nextDouble();
			Double y = (ymax) * generator.nextDouble();
			navesRestantes.add(AeroNaveFactory.getAvionPesado(new Coordenada(x,
					y)));
			this.avionesPesados -= 1;
		}

		while (this.avionesComputarizados > 0) {
			Double x = (xmax) * generator.nextDouble();
			Double y = (ymax) * generator.nextDouble();
			navesRestantes.add(AeroNaveFactory
					.getAvionComputarizado(new Coordenada(x, y)));
			this.avionesComputarizados -= 1;
		}

	}

	public void setIntervaloApariciones(long l) {
		this.intervaloApariciones = l;
	}

	public AeroNave getNave() {

		this.contadorApariciones += 1;
		if (this.navesRestantes.isEmpty())
			return null;

		if (this.contadorApariciones > this.intervaloApariciones) {
			Random generator = new Random();
			// Devuelve un elemento random de la lista, lo elimino antes
			int numeroRandom = generator.nextInt(this.navesRestantes.size());
			AeroNave aDevolver = this.navesRestantes.get(numeroRandom);
			aDevolver.alterarVelocidad(factorDeVelocidad);
			this.navesRestantes.remove(numeroRandom);
			this.contadorApariciones = 0;
			return aDevolver;
		} else {
			return null;
		}
	}

	public void agregarPista(Pista p) {
		pistas.add(p);
	}

	public boolean quedanNaves() {
		return !this.navesRestantes.isEmpty();
	}

	public Iterator<Pista> getIteradorPistas() {
		return this.pistas.iterator();
	}

	public void acelerarNaves(Double porcentaje) {
		this.factorDeVelocidad = porcentaje;
	}

	public int navesRestantes() {
		return this.navesRestantes.size();
	}

}
